package cn.south.campus.admin.campus.service.impl;

import cn.south.campus.admin.campus.mapper.ComplaintCountMapper;
import cn.south.campus.admin.campus.model.entity.ComplaintCount;
import cn.south.campus.admin.campus.model.enums.ComplaintEnums;
import cn.south.campus.admin.campus.service.ComplaintCountService;
import cn.south.campus.admin.sys.model.bo.LoginContext;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 吐槽点赞点踩表 服务实现类
 * </p>
 *
 * @author chow
 * @since 2024-12-05
 */
@Service
public class ComplaintCountServiceImpl extends ServiceImpl<ComplaintCountMapper, ComplaintCount> implements ComplaintCountService {

    @Resource
    private ComplaintCountMapper complaintCountMapper;

    @Override
    public Map<Long, boolean[]> selectMeOpt(List<Long> bizIds, Integer type) {
        Long userId = LoginContext.getContext().getId();
        if (bizIds == null || bizIds.isEmpty()) {
            return Collections.emptyMap();
        }
        LambdaQueryWrapper<ComplaintCount> wrapper = new LambdaQueryWrapper<ComplaintCount>()
                .in(ComplaintCount::getBizId, bizIds)
                .eq(ComplaintCount::getBizType, type)
                .eq(ComplaintCount::getUserId, userId);

        List<ComplaintCount> complaintCountList = complaintCountMapper.selectList(wrapper);
        Map<Long, boolean[]> res = new HashMap<>();
        if (CollectionUtils.isEmpty(complaintCountList)) {
            Map<Long, boolean[]> longMap = new HashMap<>();
            for (Long bizId : bizIds) {
                longMap.put(bizId, new boolean[]{false, false});
            }
            return longMap;
        }
        Map<Long, List<ComplaintCount>> complaintUserMap = complaintCountList.stream()
                .collect(Collectors.groupingBy(ComplaintCount::getBizId));
        complaintUserMap.forEach((item, value) -> {
            boolean[] booleans = new boolean[2];
            for (ComplaintCount complaintCount : value) {
                if (ComplaintEnums.CountType.LIKE.getCode().equals(complaintCount.getType())) {
                    booleans[0] = true;
                } else {
                    booleans[1] = true;
                }
            }
            res.put(item, booleans);
        });
        return res;
    }

    @Override
    public boolean[] selectMeOpt(Long bizId, Integer type) {
        return selectMeOpt(Collections.singletonList(bizId), type).get(bizId);
    }

    @Override
    public Map<Long, Map<Integer, Long>> selectCount(List<Long> bizIds,Integer type) {
        if (bizIds == null || bizIds.isEmpty()) {
            return Collections.emptyMap();
        }
        String bizId = "biz_id";
        QueryWrapper<ComplaintCount> wrapper = new QueryWrapper<ComplaintCount>()
                .eq("biz_type", type)
                .in(bizId, bizIds)
                .groupBy(bizId, "type")
                .select(bizId, "type", "count(1) as cnt");
        List<Map<String, Object>> complaintOptCntList = complaintCountMapper.selectMaps(wrapper);
        if (CollectionUtils.isEmpty(complaintOptCntList)) {
            return Collections.emptyMap();
        }
        Map<Long, List<Map<String, Object>>> longListMap = complaintOptCntList.stream()
                .collect(Collectors.groupingBy(item -> (Long) item.get(bizId)));
        Map<Long, Map<Integer, Long>> res = new HashMap<>();
        longListMap.forEach((item, value) -> {
            Map<Integer, Long> typeCntMap = value.stream()
                    .collect(Collectors.toMap(map -> (Integer) map.get("type"), map -> (Long) map.get("cnt")));
            res.put(item, typeCntMap);
        });
        return res;
    }

    @Override
    public Map<Integer, Long> selectCount(Long bizId,Integer type) {
        return selectCount(Collections.singletonList(bizId), type).get(bizId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cntSave(Long id, Integer code, Integer bizType) {
        Long userId = LoginContext.getContext().getId();
        LambdaQueryWrapper<ComplaintCount> wrapper = new LambdaQueryWrapper<ComplaintCount>()
                .eq(ComplaintCount::getBizId, id)
                .eq(ComplaintCount::getBizType, bizType)
                .eq(ComplaintCount::getUserId, userId);
        ComplaintCount complaintCount = complaintCountMapper.selectOne(wrapper);
        if (complaintCount == null) {
            complaintCount = new ComplaintCount();
            complaintCount.setBizId(id);
            complaintCount.setBizType(bizType);
            complaintCount.setUserId(userId);
            complaintCount.setType(code);
            complaintCountMapper.insert(complaintCount);
            return;
        }
        if (complaintCount.getType().equals(code)) {
            complaintCountMapper.deleteById(complaintCount.getId());
            return;
        }
        complaintCountMapper.deleteById(complaintCount.getId());
        complaintCount = new ComplaintCount();
        complaintCount.setBizId(id);
        complaintCount.setUserId(userId);
        complaintCount.setBizType(bizType);
        complaintCount.setType(code);
        complaintCountMapper.insert(complaintCount);
    }
}
